實作篇即將結束! 在前一部分,我們已經看到如何建立視訊通話應用程式,但是現在讓我們來處理一個重要的問題:結束視訊通話。
當用戶完成通話或離開應用程式時,應確保的視訊和音訊流被關閉,同時清理相關的資源和數據。否則,可能會導致不必要的資源浪費,並影響其他用戶的體驗,ex:無視訊時使用者的視訊設備仍開啟
async function hangUp() {
// 停止本地流和遠端流中的所有媒體軌道
localStream.current?.getTracks().forEach((track) => track.stop());
remoteStream.current?.getTracks().forEach((track) => track.stop());
// 關閉 RTCPeerConnection
peerConnection?.close();
localVideoRef.current.srcObject = null;
remoteVideoRef.current.srcObject = null;
// 重置相關狀態和視訊元素
setVideoState({
isMuted: false,
isVideoDisabled: false,
});
setPeerConnection(null);
setRoomId('');
window.alert('通話已結束');
if (roomId !== '') {
const roomRef = doc(db, 'rooms', roomId);
console.log('roomSnapshot.exists()');
await updateDoc(roomRef, { callEnded: true });
const calleeCandidatesRef = collection(roomRef, 'calleeCandidates');
const callerCandidatesRef = collection(roomRef, 'callerCandidates');
// 刪除 calleeCandidates 集合中的文件
const calleeCandidatesQuery = await getDocs(calleeCandidatesRef);
calleeCandidatesQuery.forEach(async (candidate) => {
await deleteDoc(candidate.ref);
});
// 刪除 callerCandidates 集合中的文件
const callerCandidatesQuery = await getDocs(callerCandidatesRef);
callerCandidatesQuery.forEach(async (candidate) => {
await deleteDoc(candidate.ref);
});
// 刪除 rooms 集合中的文件
await deleteDoc(roomRef);
}
}
希望透過這次的實作幫助大家在:開啟視訊、進行連線、控制媒體、結束通話這部分有幫助~
接下來會進行一些優化及額外的討論~